package com.xuexiang.xuidemo.view;

import com.xuexiang.xuidemo.util.SlidingRootNav;
import ohos.agp.animation.AnimatorProperty;
import ohos.agp.components.Component;
import ohos.agp.components.DragInfo;
import ohos.agp.components.StackLayout;
import ohos.app.Context;

public class SlidingRootNavLayout extends StackLayout implements SlidingRootNav {
//    private Component rootView;
//    private SlidingRootNavLayout mThis;

    private boolean isMenuHidden;
    private boolean isMenuLocked;
//    private boolean isContentClickableWhenMenuOpened;
    private int maxDragDistance;

    private float moveTotalX;
    private float layoutScale;
    private int slideTime;
    private int marginLeft;
//    private int layoutElevation;

    public SlidingRootNavLayout(Context context) {
        super(context);
        //mThis = this;
        setIsMenuHidden(true);
        setListener();
    }

    @Override
    public boolean isMenuClosed() {
        return isMenuHidden;
    }

    @Override
    public boolean isMenuOpened() {
        return !isMenuHidden;
    }

    @Override
    public boolean isMenuLocked() {
        return isMenuLocked;
    }

    @Override
    public void closeMenu() {
        closeMenu(true);
    }

    @Override
    public void closeMenu(boolean animated) {
        changeMenuVisibility(animated, -maxDragDistance);
        setIsMenuHidden(true);
    }

    @Override
    public void openMenu() {
        openMenu(true);
        setIsMenuHidden(false);
    }

    @Override
    public void openMenu(boolean animated) {
        changeMenuVisibility(animated, maxDragDistance);
    }

    @Override
    public void setMenuLocked(boolean locked) {
        isMenuLocked = locked;
    }

    @Override
    public SlidingRootNavLayout getLayout() {
        return this;
    }

    public void setRootView(Component view) {
        //rootView = view;
    }

    private void changeMenuVisibility(boolean animated, double xOffset) {
        if (isMenuLocked) {
            return;
        }

        double moveX;

        if ((moveTotalX >= maxDragDistance && xOffset > 0) || (moveTotalX <= 0 && xOffset < 0)) {
            return;
        }

        if (moveTotalX + xOffset >= maxDragDistance) {
            moveX = maxDragDistance - moveTotalX;
        } else if (moveTotalX + xOffset <= 0) {
            moveX = -moveTotalX;
        } else {
            moveX = xOffset;
        }
        moveTotalX += moveX;

        double scale = 1f - (1f - layoutScale) * Math.abs(moveTotalX / maxDragDistance);

        if ((moveTotalX == maxDragDistance || moveTotalX == 0) && animated) {
            AnimatorProperty animatorProperty = getComponentAt(1).createAnimatorProperty();
            animatorProperty.scaleX((float) scale).scaleY((float) scale);
            animatorProperty.moveByX((float) moveX);
            animatorProperty.setDuration((long) (slideTime * Math.abs(moveX) / maxDragDistance));
            animatorProperty.start();
        } else {
            LayoutConfig layoutConfig = (LayoutConfig) getComponentAt(1).getLayoutConfig();
            layoutConfig.setMarginLeft(marginLeft + (int) moveTotalX);
            layoutConfig.setMarginRight(-(int) moveTotalX);
            getComponentAt(1).setLayoutConfig(layoutConfig);
            getComponentAt(1).setScale((float) scale, (float) scale);
        }
    }

    public void setContentClickableWhenMenuOpened(boolean contentClickableWhenMenuOpened) {
        //isContentClickableWhenMenuOpened = contentClickableWhenMenuOpened;
    }


    public void setMaxDragDistance(int maxDragDistance) {
        this.maxDragDistance = maxDragDistance;
    }

    public void setLayoutScale(float layoutScale) {
        this.layoutScale = layoutScale;
    }

    public void setLayoutElevation(int elevation) {
//        this.layoutElevation = elevation;
    }

    private void setListener() {
        setDraggedListener(DRAG_HORIZONTAL, new DraggedListener() {
            @Override
            public void onDragDown(Component component, DragInfo dragInfo) {
            }

            @Override
            public void onDragStart(Component component, DragInfo dragInfo) {
            }

            @Override
            public void onDragUpdate(Component component, DragInfo dragInfo) {
                changeMenuVisibility(true, dragInfo.xOffset);
            }

            @Override
            public void onDragEnd(Component component, DragInfo dragInfo) {
                judgeToSlideBottom();
            }

            @Override
            public void onDragCancel(Component component, DragInfo dragInfo) {
            }
        });
    }

    //判断滑动到那边底部
    private void judgeToSlideBottom() {
        if (maxDragDistance / 2f > moveTotalX) {
            changeMenuVisibility(false, -maxDragDistance);
            setIsMenuHidden(true);
        } else {
            changeMenuVisibility(false, maxDragDistance);
            setIsMenuHidden(false);
        }
    }

    public void setSlideTime(int time) {
        slideTime = time;
    }

    public void setLayoutConfig() {
        marginLeft = getComponentAt(1).getLayoutConfig().getMarginLeft();
    }

    private void setIsMenuHidden(boolean status) {
        isMenuHidden = status;
       /* if (getComponentAt(1) != null) {
        }*/
    }
}
